/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ac.pbp.service;

import ac.pbp.core.exception.DataAdditionException;
import ac.pbp.core.exception.DataDeletionException;
import ac.pbp.core.exception.DataModificationException;
import ac.pbp.core.exception.ServiceException;
import ac.pbp.core.filter.FilterCriteria;
import ac.pbp.core.paging.FilterAndPaging;
import ac.pbp.dao.BukuDao;
import ac.pbp.dao.BukuUserDao;
import ac.pbp.dto.BukuDto;
import ac.pbp.dto.filter.BukuFilterCriteria;
import ac.pbp.model.Buku;
import ac.pbp.model.BukuUser;
import ac.pbp.model.BukuUserPK;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Kim
 */
@Component
@Transactional
public class BukuService {

    @Autowired
    private BukuDao bukuDao;
    @Autowired
    private BukuUserDao bukuUserDao;

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = {Exception.class})
    public void addBuku(Buku buku, String kodePengarang, String cover) throws ServiceException {

        if (buku.getKodeBuku() != null) {

            buku.setPengarang(Buku.newInstance(kodePengarang));
            buku.setCover(cover);
            buku.setTglInsert(new Date());

            bukuDao.add(buku);
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = {Exception.class})
    public String updateBuku(Buku buku, String kodePengarang, String cover) throws ServiceException {

        if (buku.getKodeBuku() != null) {
            Buku bukuInner = bukuDao.load(buku.getKodeBuku());
            bukuInner.setNamaBuku(buku.getNamaBuku());
            bukuInner.setDescBuku(buku.getDescBuku());
            bukuInner.setPengarang(Buku.newInstance(kodePengarang));
            bukuInner.setKodeGenre(buku.getKodeGenre());
            bukuInner.setCover(cover);
            bukuDao.update(bukuInner);
        }

        return buku.getKodeBuku();
    }

    @Transactional(readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = {Exception.class})
    public Buku loadBuku(String kodeBuku) {
        return bukuDao.load(kodeBuku);
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = {Exception.class})
    public void deleteBuku(String idArray) {
        String[] idArrayRay = idArray.split(",");
        for (int i = 0; i < idArrayRay.length; i++) {
            try {
                if (!idArrayRay[i].equals("")) {
                    bukuDao.delete(bukuDao.load(idArrayRay[i]));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @SuppressWarnings("unchecked")
    public BukuDto filterBuku(FilterCriteria filterCriteria) {
        BukuDto bukuDto = new BukuDto();

        bukuDto.setBukuList(FilterAndPaging.filter(this.bukuDao, filterCriteria));
        bukuDto.setFilterCriteria((BukuFilterCriteria) filterCriteria);

        return bukuDto;
    }

    public List<Buku> getBukuByGenre(String genre) {
        return bukuDao.getBukuByGenre(genre);
    }

    public void addToShelf(String kodeUser, String kodeBuku) throws DataAdditionException {

        BukuUserPK bukuUserPk = new BukuUserPK(kodeUser, kodeBuku);
        BukuUser bukuUser = new BukuUser();

        bukuUser.setBukuUserPk(bukuUserPk);
        bukuUser.setTanggal_status_buku(new Date());
        bukuUser.setTanggalReviewBuku(null);
        bukuUser.setRatingBuku(null);
        bukuUser.setReviewBuku(null);

        bukuUserDao.add(bukuUser);
    }

    public Buku detailBuku(String kodeBuku) {

        return bukuDao.load(kodeBuku);
    }

    public List<Buku> loadAll() {
        return bukuDao.loadAll();
    }

    public List<BukuUser> loadUserBuku(String kodeUser) {

        return bukuDao.loadUserBuku(kodeUser);

    }

    public void deleteMyBooks(String kodeUser, String kodeBuku) throws DataDeletionException {

        bukuUserDao.deleteMyBooks(kodeUser, kodeBuku);
    }

    public List<Buku> loadBukuPengarang(String kodePengarang) {
        return bukuDao.loadBukuPengarang(kodePengarang);
    }

    public List<Buku> loadNewestBooks() {
        return bukuDao.loadNewestBooks();
    }

    public BukuUser loadBukuUser(String kodeUser, String kodeBuku) {
        return bukuUserDao.loadBukuUser(kodeUser, kodeBuku);
    }

    public void rateBook(String kodeUser, String kodeBuku, Integer rate) throws DataAdditionException {

        BukuUser bukuUser = bukuUserDao.loadBukuUser(kodeUser, kodeBuku);

        if (bukuUser == null) {
            BukuUserPK bukuUserPk = new BukuUserPK(kodeUser, kodeBuku);
            bukuUser = new BukuUser();
            bukuUser.setBukuUserPk(bukuUserPk);
        }
        
        bukuUser.setRatingBuku(rate);
        bukuUser.setTanggal_status_buku(new Date());
        bukuUser.setTanggalReviewBuku(null);
        bukuUser.setReviewBuku(null);

        bukuUserDao.add(bukuUser);
    }
    
    public void updateBukuUser(BukuUser userBuku) throws DataModificationException {
        bukuUserDao.update(userBuku);
    }

    public List<BukuUser> loadReview(String kodeBuku, String kodeUser) {
        return bukuUserDao.loadReview(kodeBuku, kodeUser);
    }
    
    
}
